﻿#region Copyright and Licensing Notice
// Copyright (C) 2011 Steven Bosnick
// 
// This program is open source software; you can redistribute it 
// and/or modifiy it under the terms of the Eclipse Public License,
// version 1.0.
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A 
// PARTICULAR PURPOSE. See the Eclipse Public License for more
// details.
// 
// You should have received a copy of the Eclipse Public License 
// along with this program; if not, you can find a copy at
// "http://www.opensource.org/licenses/eclipse-1.0.php".
#endregion

using System;
using System.IO;

namespace BitwiseOre.IO
{
    ///<summary>
    /// Defines the methods to accept and wait for an incoming conection request.
    ///</summary>
    public interface IListener
    {
        /// <summary>
        /// Accepts a pending connection request.
        /// </summary>
        /// <exception cref="TimeoutException">
        ///     The accept operation timed out.
        /// </exception>
        /// <exception cref="IOException">
        ///     An unexpected problem occured when attempting to accept a connection.
        /// </exception>
        /// <returns>
        ///     A <see cref="DisconnectableStream"/> representing the new conntection.
        /// </returns>
        DisconnectableStream Accept();

        /// <summary>
        /// Begins an asynchronous operation to accept a pending connection request.
        /// </summary>
        /// <param name="callback">
        ///     An <see cref="AsyncCallback"/> that references the method to invoke when
        ///     the operation is complete.
        /// </param>
        /// <param name="state">
        ///     A user-defined object containing information about the accept operation.
        /// </param>
        /// <returns>
        ///     An <see cref="IAsyncResult"/> that reference the asynchronous accept operation.
        /// </returns>
        IAsyncResult BeginAccept(AsyncCallback callback, object state);

        /// <summary>
        /// Completes an asynchronous operation to accept a pending connection request.
        /// </summary>
        /// <param name="asyncResult">
        ///     The asynchroous operation to complete. Must be the return value of
        ///     <see cref="BeginAccept"/>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="asyncResult"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     <paramref name="asyncResult"/> is not the return value of <see cref="BeginAccept"/>.
        /// </exception>
        /// <exception cref="TimeoutException">
        ///     The accept operation timed out.
        /// </exception>
        /// <exception cref="IOException">
        ///     An unexpected problem occured when attempting to accept a connection.
        /// </exception>
        /// <returns>
        ///     A <see cref="DisconnectableStream"/> representing the new connection.
        /// </returns>
        DisconnectableStream EndAccept(IAsyncResult asyncResult);

        ///<summary>
        /// Gets or set a value, in milliseconds, that determines how long the listener will
        /// attempt to accept a pending connection request before timing out.
        ///</summary>
        int AcceptTimeout { get; set; }

        /// <summary>
        /// Gets or set a value, in miliseconds, that determines how long the listener
        /// will wait for a connection request before timing out.
        /// </summary>
        int WaitForTimeout { get; set; }

        ///<summary>
        /// Blocks waiting for a connection request to this listner.
        ///</summary>
        /// <exception cref="TimeoutException">
        ///     The wait for operation timed out.
        /// </exception>
        /// <exception cref="IOException">
        ///     An unexpected problem occured when attempting to wait for a pending connection.
        /// </exception>
        void WaitFor();

        ///<summary>
        /// Begins an asynchronous operation to wait for a connection request
        /// to this listner.
        ///</summary>
        /// <param name="callback">
        ///     An <see cref="AsyncCallback"/> that references the method to invoke when
        ///     the operation is complete.
        /// </param>
        /// <param name="state">
        ///     A user-defined object containing information about the accept operation.
        /// </param>
        /// <returns>
        ///     An <see cref="IAsyncResult"/> that reference the asynchronous wait operation.
        /// </returns>
        IAsyncResult BeginWaitFor(AsyncCallback callback, object state);

        /// <summary>
        /// Completes an asynchronous operation to wait for a connection request.
        /// </summary>
        /// <param name="asyncResult">
        ///     The asynchronous operation to complete. Must be a return values from
        ///     <see cref="BeginWaitFor"/>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="asyncResult"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     <paramref name="asyncResult"/> is not the return value of <see cref="BeginWaitFor"/>.
        /// </exception>
        /// <exception cref="TimeoutException">
        ///     The wait for operation timed out.
        /// </exception>
        /// <exception cref="IOException">
        ///     An unexpected problem occured when attempting to wait for a pending connection.
        /// </exception>
        void EndWaitFor(IAsyncResult asyncResult);
    }
}